package edu.gtcfla.km.admin.appmodules.service.impl;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.vsg.biz.BusinessEntityFactory;
import org.vsg.biz.BusinessOperationException;
import org.vsg.biz.account.Module;
import org.vsg.biz.account.ModuleFunction;
import org.vsg.biz.account.Permission;
import org.vsg.biz.account.Role;
import org.vsg.biz.account.repositories.BindingActionRepo;
import org.vsg.biz.account.repositories.MenuRepo;
import org.vsg.biz.account.repositories.ModuleFunctionRepo;
import org.vsg.biz.account.repositories.ModuleRepo;
import org.vsg.biz.account.repositories.PermissionRepo;
import org.vsg.biz.account.repositories.ResourceRepo;
import org.vsg.biz.account.repositories.RoleRepo;
import org.vsg.biz.account.repositories.UrlRepo;
import org.vsg.common.web.json.SelectItem;
import org.vsg.module.resources.register.ModuleProxyManager;

import edu.gtcfla.km.admin.appmodules.service.ModuleManagerService;
import edu.gtcfla.km.admin.appmodules.vo.ModuleEditionVO;
import edu.gtcfla.km.admin.appmodules.vo.ModuleFunctionInModuleVO;
import edu.gtcfla.km.admin.appmodules.vo.ModulePermissionVO;


public class ModuleManagerServiceImpl implements ModuleManagerService {

	@Resource
	private ModuleRepo<Module,String> moduleRepo;
	
	@Resource
	private ModuleFunctionRepo<ModuleFunction,String> moduleFunctionRepo;
	
	@Resource
	private PermissionRepo permissionRepo;
	
	@Resource
	private MenuRepo menuRepo;
	
	@Resource
	private UrlRepo urlRepo;

	@Resource
	private RoleRepo roleRepo;
	
	@Resource
	private ResourceRepo resourceRepo;
	
	@Resource
	private BindingActionRepo bindingActionRepo;
	
	@Autowired(required=false)
	private ModuleProxyManager moduleProxyManager;
	
	private static BusinessEntityFactory entityFactory = BusinessEntityFactory.getInstance();	

	private static final Logger logger = LoggerFactory.getLogger(ModuleManagerServiceImpl.class);

	@Override
	public Set<ModuleEditionVO> findAllModules() throws BusinessOperationException {
		// TODO Auto-generated method stub
		Set<Module> modules = moduleRepo.findAll();
		
		Set<ModuleEditionVO> moduleEditions = new LinkedHashSet<ModuleEditionVO>();
		
		for (Module mod : modules) {
			
			ModuleEditionVO modEditVo = new ModuleEditionVO(mod);
			moduleEditions.add( modEditVo );
		}

		
		return moduleEditions;
	}

	@Override
	public Set<ModuleEditionVO> findUnloadedModules() throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set<ModuleFunctionInModuleVO> findFunsByModResId(String moduleResId)
			throws BusinessOperationException {
		
		Set<ModuleFunction>  funs = moduleFunctionRepo.findAllByModuleId( moduleResId );
		
		Set<ModuleFunctionInModuleVO> funSet = new LinkedHashSet<ModuleFunctionInModuleVO>();
		
		for (ModuleFunction fun : funs) {
			ModuleFunctionInModuleVO funInMod = new ModuleFunctionInModuleVO( fun );
			
			funSet.add( funInMod );
		}

		return funSet;
	}

	@Override
	public Set<ModulePermissionVO> listPermissionModulesByRoleId(String roleId)
			throws BusinessOperationException {
		
		// --- find all available permission ---
		Iterable<Module> moduleIter = moduleRepo.findAllAvailable();
		
		Map<String, Permission> permMap = permissionRepo.findModulePermissionMapByRoleId(roleId);

		// --- show module iter ---
		Set<ModulePermissionVO> result = new LinkedHashSet<ModulePermissionVO>();
		
		for (Module mod : moduleIter) {
			ModulePermissionVO mpvo = new ModulePermissionVO(mod);
			
			Permission perm = permMap.get(mpvo.getId());
			if (perm != null) {
				mpvo.setAcl( perm.getAccessControl() );
			} else {
				mpvo.setAcl("");
			}
			result.add(mpvo);
		}

		return result;
	}

	@Override
	public Set<ModuleFunction> findFunctionsByModule(
			org.vsg.biz.account.Module module) throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}


	@Override
	public void authModule(String roleId, Set<ModulePermissionVO> permVos)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void authModuleWithUnderRes(String roleId,
			Set<ModulePermissionVO> permVos) throws BusinessOperationException {
		// TODO Auto-generated method stub
		Set<String> resIds = new LinkedHashSet<String>();
		
		Set<Permission> permSet = new LinkedHashSet<Permission>();
		
		Role role = roleRepo.findOne( roleId );
		for (ModulePermissionVO permItem : permVos ) {
			resIds.add( permItem.getId() );
			
			org.vsg.biz.account.Resource res = resourceRepo.findOne( permItem.getId() );
			
			Permission perm = entityFactory.create( Permission.class );
			perm.setAccessControl( permItem.getAcl() );
			perm.setAssignedRole( role );
			perm.setAssignedResource( res );
			permSet.add( perm );
		}

		permissionRepo.removePermissionForModule(roleId , resIds);
		
		// --- add new permission ---
		permissionRepo.saveAll( permSet );
	}

	@Override
	public Set<SelectItem> findAllSelModule() throws BusinessOperationException {
		// TODO Auto-generated method stub
		Iterable<Module> moduleIter = moduleRepo.findAllAvailable();
		
		Set<SelectItem> selItems = new LinkedHashSet<SelectItem>();
		
		for (Module mod : moduleIter) {
			SelectItem item = new SelectItem();
			item.setId( mod.getId() );
			item.setName( mod.getName() );
			
			selItems.add( item );
		}
		
		return selItems;
	}
	

	
}
